/*
  Buffer的基本操作
  Buffer本质上就是字节数组
  1，构造方法(类)
  2，静态方法
  3，实例方法
 
*/
// let buf = Buffer.alloc(5)
// console.log(buf)

// let buf = Buffer.from('hello')
// console.log(buf)

// let buf = Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72])
// console.log(buf.toString())


/*实例方法*/

// 向buffer对象中写入内容
// let buf = Buffer.alloc(5)
// buf.write('hello', 2, 2)
// console.log(buf)

//截取新的buffer对象
// let buf = Buffer.from('hello')
// let buf1 = buf.slice(2, 3)
// console.log(buf === buf1)
// console.log(buf1.toString())

//把buf对象转成字符串buf.toString()

//把buf对象转成json形式的字符串, toJSON不需要显示的调用，当JSON.stringify方法调用的时候会自动调用toJSON方法
// const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5,])
// const buf = Buffer.from('hello')
// const json = JSON.stringify(buf)
// console.log(json)


/*
  路径操作
*/
const path = require('path')

//获取路径的最后一部分，获取到文件跟扩展名, 可通过第二个参数过滤掉后缀名
// console.log(path.basename('/foo/bar/baz/asfd/index.html', '.html'))

//获取路径
// console.log(path.dirname('/foo/bar/baz/asfd/index.html'))

//获取文件扩展名
// console.log(path.extname('/foo/bar/baz/asfd/index.html'))

//路径的格式化处理
//path.format() obj->string
//path.parse() string->obj
// let obj = path.parse(__filename)
// console.log(obj)

// 方便获取到文件的任何一部分
// { root: 'D:\\', 文件的根路经
//   dir: 'D:\\workspace\\node-study', 文件的全路径
//   base: '02.js', 文件的名称
//   ext: '.js', 扩展名
//   name: '02' 文件名称
// }

// let objpath = {
//   root: 'D:\\', 
//   dir: 'D:\\workspace\\node-study', 
//   base: '02.js', 
//   ext: '.js', 
//   name: '02'
// }
// console.log(path.format(objpath))

//判断是否为绝对路径
// console.log(path.isAbsolute('c:/foo/..'))
// console.log(path.isAbsolute('../foo/test.css'))

//路径连接, 还可以支持..(上级路径)跟.(当前路径)
// console.log(path.join(__dirname, 'bar', 'baz', 'test.html'))

//规范化路径
// console.log(path.normalize('/foo/bar//baz/asdf/quux/..'))
// console.log(path.normalize('C:\\temp\\\\foo\\bar\\..\\'))

//相对路径, 第二个路径相对第一个的路径
// console.log(path.relative('/data/orandea/test/aaa', '/data/orandea/qw/test'))

//解析路径
// console.log(path.resolve('/foo/bar', './baz'))
// console.log(path.resolve('/foo/bar', '/temp/file/'))
// console.log(path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif'))

//两个特殊属性
// console.log(path.delimiter) //标识路径分隔符(windows是; Linux是:)
// console.log(path.sep) //路径片段分隔符(windows是/ linux是\)

/*
  异步I/O input/output
  1.文件操作
  2.网络操作
  在浏览器中也存在异步操作
  1.定时任务
  2.事件处理
  3.Ajax回调处理

  js的运行是单线程的
  引入了事件队列机制

  node.js的事件模型与浏览器中的事件模型类似
  单线程+事件队列

  node.js中异步执行的任务:
  1.文件I/O
  2.网络I/O

  基于回调函数的编码风格
*/

const fs = require('fs')

// fs.stat(path.resolve(__dirname, '01.js'), (err, stat) => {
// 	if (err) return
// 		console.log(stat)
// 	if (stat.isFile()) {
// 	  console.log('是文件')
// 	}
// 	if (stat.isDirectory()) {
// 	  console.log('是目录')
// 	}
// })

// let ret = fs.statSync(path.resolve(__dirname, '01.js'))
// console.log(ret)

//读文件操作
// fs.readFile(path.resolve(__dirname, '01.js'), (err, data) => {
// 	if (err) return
// 	console.log(data.toString())
// })
//如果有第二个参数并且是编码，那么回调函数获取到的数据就是字符串，如果没有第二个参数得到的是buffer实例对象
// fs.readFile(path.resolve(__dirname, '01.js'), 'utf8', (err, data) => {
// 	if (err) return
// 	console.log(data)
// })

// let ret = fs.readFileSync(path.resolve(__dirname, '01.js'), 'utf8')
// console.log(ret)

/*
  类继承
*/

// $.ajax()这就是一个js的静态方法
// class Animal {
// 	//静态方法(只能通过类名来调用，不能使用实例对象调用)
// 	static showInfo() {
// 		console.log('hi')
// 	}
// 	//构造函数
// 	constructor(name) {
// 		this.name = name
// 	}
// 	showName() {
// 		console.log(this.name)
// 	}
// }
// let a = new Animal('spike')
// a.showName()
// Animal.showInfo()

//类的继承extends
// class Dog extends Animal {
// 	constructor(name,color) {
// 		super(name) // super用来调用父类
//     this.color = color
// 	}
// 	showColor() {
// 		console.log(this.color)
// 	}
// }
// let dog = new Dog('黄狗', 'yellow')
// dog.showName()
// dog.showColor()
// Dog.showInfo()//继承的时候静态方法也是使用类名调用的


/*
  大文件操作(流式操作)
  fs.createReadStream(path[, options])
  fs.createWriteStream(path[, options])
*/
// let spath = path.join(__dirname, '01.js')
// let dpath = path.join(__dirname, '03.js')
// let readStream = fs.createReadStream(spath)
// let writeStream = fs.createWriteStream(dpath)

// let num = 1
// readStream.on('data', chunk => {
//   num++
//   writeStream.write(chunk)
// })
// readStream.on('end', () => {
// 	console.log('文件处理完成' + num)
// })
// readStream.pipe(writeStream)
//一步完成
// fs.createReadStream(spath).pipe(fs.createWriteStream(dpath))


/*
  目录操作
  1.创建目录
  fs.mkdir(path[, options], callback)
  fs.mkdirSync(path[, options])
  2.读取目录
  fs.readdir(path[, options], callback)
  fs.readdirSync(path[, options])
  3.删除目录
  fs.rmdir(path, callback)
  fs.rmdirSync(path)
*/

//创建目录
// fs.mkdir(path.join(__dirname, 'abc'), err => {
//   console.log(err)
// })

// fs.mkdirSync(path.join(__dirname, 'hello'))

//读取目录
// fs.readdir(path.join(__dirname), (err, files) => {
// 	console.log(err)
// 	console.log(files)
// })

//删除目录
// fs.rmdir(path.join(__dirname, 'abc'), err => {
// 	console.log(err)
// })

// fs.rmdirSync(path.join(__dirname, 'abc'))

//文件复制功能

function copyProject(newProject, project) {
	let ret = path.parse(project)
	fs.mkdir(path.join(newProject, ret.name), (err) => {
		if (err) return
		console.log('项目创建成功')
	})
	fs.readdir(path.resolve(project), (err, files) => {
		if (err) return
    files.forEach(item => {
    	fs.stat(path.join(project, item), (err, stat) => {
    		if (stat.isFile()) {
	  			console.log('是文件')
	  			fs.createReadStream(path.join(project, item)).pipe(fs.createWriteStream(path.join(newProject, ret, item)))
				}
				if (stat.isDirectory()) {
					copyProject(path.join(newProject, item), path.join(project, item))
	  			console.log('是目录')
				}
    	})
    })
	})
}
copyProject(path.join(__dirname, '../..'), path.join(__dirname))
